
package jwww.service;

import java.io.*;
import java.net.Socket;

import jwww.handlers.BinaryFile;

import org.apache.log4j.Logger;

class ServerThread
extends Thread
{
  int uniquifier = 0;

  Socket         socket = null;
  BufferedReader reader = null;
  PrintWriter    writer = null;

  Service service = null;

  ServerThread(Socket socket, Service service)
  {
    this.socket  = socket;
    this.service = service;
    setName("ServerThread-" + + unique());
  }

  @Override
  public void run()
  {
    try
    {
      setup();
      handle();
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
  }

  void setup()
    throws IOException
  {
    reader =
      new BufferedReader
      (new InputStreamReader
       (socket.getInputStream()), 1);
    writer =
      new PrintWriter
       (new OutputStreamWriter
        (socket.getOutputStream()));
  }

  void handle()
  throws IOException
  {
    String   query  = reader.readLine();
    if (query == null)
      return;
    Logger.getLogger("JWWW").info("query:  " + query);
    String[] tokens = query.split("\\s");
    String   method = tokens[0];
    String   target = tokens[1];
    respond(method, target);
  }

  /* Processes method, target by calling service.
     Adds termination to response headers.
  */
  void respond(String method, String target)
  {
    Page page = null;
    if (method.equals("GET"))
    {
      page = service.get(target);

      page.makeHeaders();
      writer.print(page.headers + "\r\n");
      if (page instanceof BinaryFile)
      {
        try
        {
          writer.flush();
          ((BinaryFile) page).stream(socket.getOutputStream());
        }
        catch (IOException e)
        {
          e.printStackTrace();
          writer.close();
        }
      }
      else
      {
        writer.print(page.body + "\r\n");
      }
    }
    else if (method.equals("HEAD"))
    {
      page = service.head(target);
      page.makeHeaders();
      writer.print(page.headers + "\r\n");
    }

    Logger logger = Logger.getLogger("JWWW");
    logger.trace(page.headers);
    logger.trace(page.body);

    writer.flush();
    writer.close();
  }

  String target(String query)
  {
    String[] tokens = query.split("\\s");
    return tokens[1];
  }

  synchronized int unique()
  {
    return uniquifier++;
  }
}
